<?php
namespace Kuoqi\Api\Weixin\Mp;
use Kuoqi\Api\Weixin\Tools;
use Kuoqi\Api\Weixin\Config;

/**
 * 数据验签的模块，包含授权
 * Class Auth
 * @package Kuoqi\Api\Weixin\Mp
 */
class Auth{

    //微信授权第一步的简版获取openid
    public function authorizeSimple($redirect_url = '',$callback_url = '',$clientState = '123456'){
        if(!$redirect_url){
            throw new \Kuoqi\Error('[redirect_url]参数必须为完成地址，且可访问');
        }
        $state_data = array(
            'app_id'=>Config::$mp_appid,
            'app_secret'=>Config::$mp_secret,
            'redirect_url'=>$redirect_url,
            'scope'=>'snsapi_base',//
            'callback_url'=>$callback_url,
            'client_state'=>$clientState,//用户封装自定义字段
            'time'=>time(),
        );
        $state = md5(serialize($state_data));
        tools::setCache($state,serialize($state_data),3600);
        $url = sprintf('https://open.weixin.qq.com/connect/oauth2/authorize?appid=%s&redirect_uri=%s&response_type=%s&scope=%s&state=%s#wechat_redirect',
            Config::$mp_appid,
            urlencode($redirect_url),
            'code',
            'snsapi_base',
            $state
        );
        Header("HTTP/1.1 303 See Other");
        Header("Location: " . $url);
        exit;
    }
    /**
     * 微信openid授权第一步
     * @param string $redirect_url
     * @param string $callback_url
     * @param string $clientState
     * @throws \Kuoqi\Error
     */
    public function authorize($redirect_url = '',$callback_url = '',$clientState = '123456'){
        if(!$redirect_url){
            throw new \Kuoqi\Error('[redirect_url]参数必须为完成地址，且可访问');
        }
        $state_data = array(
            'app_id'=>Config::$mp_appid,
            'app_secret'=>Config::$mp_secret,
            'redirect_url'=>$redirect_url,
            'scope'=>'snsapi_userinfo',//
            'callback_url'=>$callback_url,
            'client_state'=>$clientState,//用户封装自定义字段
            'time'=>time(),
        );
        $state = md5(serialize($state_data));
        tools::setCache($state,serialize($state_data),3600);
        $url = sprintf('https://open.weixin.qq.com/connect/oauth2/authorize?appid=%s&redirect_uri=%s&response_type=%s&scope=%s&state=%s#wechat_redirect',
            Config::$mp_appid,
            urlencode($redirect_url),
            'code',
            'snsapi_userinfo',
            $state
        );
        Header("HTTP/1.1 303 See Other");
        Header("Location: " . $url);
        exit;
    }

    /**
     * 微信openid授权第二步
     * @param $code 微信返回的code
     * @param $state 微信返回的state信息
     * @return array 返回是一个数组信息
     */
    public function getAuthAccessToken($code,$state){
        $data = tools::getCache($state);
        $data = unserialize($data);
        //使用接口的方式请求
        $curl = sprintf('https://api.weixin.qq.com/sns/oauth2/access_token?appid=%s&secret=%s&code=%s&grant_type=authorization_code',
            $data['app_id'],
            $data['app_secret'],
            $code
        );
        $response = new response(tools::sendTo($curl));
        return $response->toArray($data);
    }

    /**
     * 微信用户授权第三步，返回用户地址
     * @param $openid
     * @param $callurl
     * @param $clientState
     */
    public function callClient($openid,$callurl,$clientState){
        $urar = parse_url($callurl);
        $url = sprintf('%s://%s%s%s',
            (isset($urar['scheme'])?($urar['scheme']):'http'),
            (isset($urar['host'])?$urar['host']:'www.kuoqps.cn'),
            (isset($urar['path'])?$urar['path']:'/'),
            (isset($urar['query'])?('?'.$urar['query'].'&openid='.$openid.'&state='.$clientState):('?openid='.$openid.'&state='.$clientState))
        );
        Header("HTTP/1.1 303 See Other");
        Header("Location: " . $url);
        exit;
    }

    //获取唯一token
    static function getToken(){
        //判定token是否存在和是否过期
        $token = tools::getCache(self::$tmp_token_name.'.'.self::$app_mp_id);
        if($token){
            return $token;
        }else{
            //如果token不存在，则重新获取token
            $auth = new auth();
            $tkarr = $auth->accessToken();
            if($tkarr['errcode']){
                //这个是唯一一个需要用到错误模块的地方
                throw new \Kuoqi\Error($tkarr['message']);
            }
            $token = $tkarr['data']['access_token'];
            tools::setCache(
                self::$tmp_token_name,
                $token,
                ($tkarr['data']['expires_in'] - 60)
            );
            return $token;
        }
    }

    //获取access_token
    public function accessToken(){
        $url = sprintf($this->access_token,
            \kweixin::$app_mp_id,
            \kweixin::$app_mp_secret
        );
        $response = new response(tools::curl($url));
        return $response->toArray();
    }

    //获取ticket
    public function getTicket(){
        $url = sprintf($this->ticketurl,
            \kweixin::getToken()
        );
        $response = new response(tools::curl($url));
        return $response->toArray();
    }

}